import fs from 'fs';
import path from 'path';
import readline from 'readline';
import os from 'os';
import chalk from 'chalk';
import process from 'process';
import {spawnSync} from 'child_process';
import {fetchUserOpsToken} from '../utils/OpsUser.js';
import {OPSConstant} from '../constant/OPSConstant.js';
import {FeishuBot} from '../utils/BotClient.js';
import {AppUtil} from '../utils/AppUtil.js';
import {opsClient} from '../utils/OpsClient.js';

/**
 * nb-init 命令处理器
 * 初始化 ops 工作环境和配置文件
 */

// 创建readline接口用于用户输入
function createReadlineInterface() {
    return readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
}

// 异步输入函数
function askQuestion(rl, question) {
    return new Promise((resolve) => {
        rl.question(question, (answer) => {
            resolve(answer);
        });
    });
}

// 日志函数
function logInfo(message) {
    console.log(chalk.cyanBright(`[INFO] ${message}`));
}

function logSuccess(message) {
    console.log(chalk.green(`[SUCCESS] ${message}`));
}

function logWarning(message) {
    console.log(chalk.yellow(`[WARNING] ${message}`));
}

function logError(message) {
    console.log(chalk.red(`[ERROR] ${message}`));
}

function delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

const SKIP_LEADER_USERS = new Set(['leo', 'leo.kuang', 'he.wu', 'jack.he', 'kadin.tang']);
const DACS_PATH_REGEX = /^([a-zA-Z]:)?\/meili\/[^/]+\/103(\/|$)/;
const WIN_DOMAIN_DRIVE_REGEX = /^([op]):\//i;

function extractDacsContext(currentDir) {
    const normalized = (currentDir || '').replace(/\\/g, '/');
    const domainDriveMatch = process.platform === 'win32' ? normalized.match(WIN_DOMAIN_DRIVE_REGEX) : null;
    const domainDrivePrefix = domainDriveMatch ? `${domainDriveMatch[1].toUpperCase()}:` : null;
    const isWinDomainDrive = Boolean(domainDrivePrefix);
    if (!DACS_PATH_REGEX.test(normalized) && !isWinDomainDrive) {
        return null;
    }

    // 优先使用标准 /meili/<user>/103 目录识别
    const segments = normalized.split('/').filter(segment => segment.length > 0);
    const meiliIndex = segments.indexOf('meili');
    if (meiliIndex === -1) {
        // 域内盘符兜底识别（Windows 域内挂载，支持 O/P）
        if (isWinDomainDrive) {
            const opsRootDir = path.join(`${domainDrivePrefix}\\`, 'ops');
            const dacsUser = os.userInfo().username;
            return {dacsUser, opsRootDir, normalizedPath: normalized};
        }
        return null;
    }
    const dacsUser = segments[meiliIndex + 1];
    const envMarker = segments[meiliIndex + 2];
    if (!dacsUser || envMarker !== '103') {
        // 域内盘符兜底识别（Windows 域内挂载，支持 O/P）
        if (isWinDomainDrive) {
            const opsRootDir = path.join(`${domainDrivePrefix}\\`, 'ops');
            const fallbackUser = os.userInfo().username;
            return {dacsUser: fallbackUser, opsRootDir, normalizedPath: normalized};
        }
        return null;
    }
    const hasLeadingSlash = normalized.startsWith('/');
    const prefixParts = segments.slice(0, meiliIndex + 3);
    const prefixPath = `${hasLeadingSlash ? '/' : ''}${prefixParts.join('/')}`;
    const opsRootDir = path.join(prefixPath, 'Documents', 'ops');
    return {dacsUser, opsRootDir, normalizedPath: normalized};
}

async function askDacsUsagePreference(rl, isDacsDetected = false) {
    while (true) {
        const option1 = `[1] 是（我希望在 DACS 内使用）${isDacsDetected ? ' ✓ 检测到当前目录为 DACS 域内' : ''}`;
        const option2 = `[2] 否（我已经卸载了 DACS）${isDacsDetected ? '' : '✓ 检测到当前目录为域外'}`;
        const question = [
            '您是否希望在 DACS（域内）使用？',
            option1,
            option2,
            '请输入 1 或 2: '
        ].join('\n');
        const answer = await askQuestion(rl, question);
        const normalized = (answer || '').trim().toLowerCase();
        if (normalized === '1' || normalized === '是' || normalized === 'y' || normalized === 'yes') {
            return true;
        }
        if (normalized === '2' || normalized === '否' || normalized === 'n' || normalized === 'no') {
            return false;
        }
        logWarning('无效的选择，请输入 1(是) 或 2(否)。');
    }
}

async function selectBrowser(rl, options = {}) {
    const {useDacs = false} = options;
    const question = [
        '请选择主要使用浏览器：(您使用公司 vops 的浏览器，请固定使用下方的某一个。否则会出现经常需要重新登录的情况)',
        '[1] Edge（默认，推荐，您将有最好的体验）',
        '[2] Chrome',
        '请输入 1 或 2: '
    ].join('\n');
    const answer = await askQuestion(rl, question);
    const browserChoice = (answer || '').trim().toLowerCase();
    const useChrome = browserChoice === '2' || browserChoice === 'chrome' || browserChoice === 'c';
    const repoUrl = useChrome
        ? (useDacs ? 'http://gitlab.inzwc.com/vangelis.wang/chrome-nicole-v2.git' : 'https://gitee.com/vangelisx/chrome-nicole-v2.git')
        : (useDacs ? 'http://gitlab.inzwc.com/vangelis.wang/chrome-nicole.git' : 'https://gitee.com/vangelisx/chrome-nicole.git');
    const browserLabel = useChrome ? 'Chrome' : 'Edge';
    return {useChrome, repoUrl, browserLabel};
}

async function openUrlWithPreferredBrowser(browserSelection, url) {
    const selection = browserSelection || {};
    const useChrome = Boolean(selection.useChrome);
    const platform = process.platform;
    const tryRun = async (command, args = [], options = {}) => {
        await AppUtil.runCommand(command, args, {
            detached: true,
            resolveOnSpawn: true,
            ignoreExitCode: true,
            ...options
        });
    };

    try {
        if (platform === 'darwin') {
            const appName = useChrome ? 'Google Chrome' : 'Microsoft Edge';
            await tryRun('open', ['-a', appName, url]);
            return true;
        }
        if (platform === 'win32') {
            if (useChrome) {
                await tryRun('cmd', ['/c', 'start', '', 'chrome', url], {windowsHide: true});
            } else {
                await tryRun('cmd', ['/c', 'start', '', `microsoft-edge:"${url}"`], {windowsHide: true});
            }
            return true;
        }
        const candidates = useChrome
            ? [
                ['google-chrome', [url]],
                ['chrome', [url]],
                ['chromium-browser', [url]]
            ]
            : [
                ['microsoft-edge', [url]],
                ['edge', [url]]
            ];
        for (const [command, args] of candidates) {
            try {
                await tryRun(command, args);
                return true;
            } catch (error) {
                // continue
            }
        }
        await tryRun('xdg-open', [url]);
        return true;
    } catch (error) {
        logWarning(`按偏好浏览器打开链接失败: ${error.message}`);
        return false;
    }
}

async function openGitLabTokenPage(browserSelection) {
    const url = 'http://gitlab.inzwc.com/-/profile/personal_access_tokens';
    try {
        logInfo('尝试在浏览器打开 GitLab Token 页面，若未自动弹出请手动访问。');
        const opened = await openUrlWithPreferredBrowser(browserSelection, url);
        if (!opened) {
            await AppUtil.openUrl(url);
        }
    } catch (error) {
        logWarning(`自动打开 GitLab Token 页面失败: ${error.message}`);
    }
}

async function openBrowserExtensionsPage(browser) {
    const isChrome = browser === 'chrome';
    const extensionUrl = isChrome ? 'chrome://extensions/' : 'edge://extensions/';
    const platform = process.platform;
    const tryRun = async (command, args = [], options = {}) => {
        await AppUtil.runCommand(command, args, {
            detached: true,
            resolveOnSpawn: true,
            ignoreExitCode: true,
            ...options
        });
    };

    try {
        if (platform === 'darwin') {
            const appName = isChrome ? 'Google Chrome' : 'Microsoft Edge';
            await tryRun('open', ['-a', appName, extensionUrl]);
        } else if (platform === 'win32') {
            if (isChrome) {
                await tryRun('cmd', ['/c', 'start', '', 'chrome', 'chrome://extensions/'], {windowsHide: true});
            } else {
                await tryRun('cmd', ['/c', 'start', '', 'microsoft-edge:"edge://extensions/"'], {windowsHide: true});
            }
        } else {
            const candidates = isChrome
                ? [
                    ['google-chrome', [extensionUrl]],
                    ['chrome', [extensionUrl]],
                    ['chromium-browser', [extensionUrl]]
                ]
                : [
                    ['microsoft-edge', [extensionUrl]],
                    ['edge', [extensionUrl]]
                ];
            let opened = false;
            for (const [command, args] of candidates) {
                try {
                    await tryRun(command, args);
                    opened = true;
                    break;
                } catch (error) {
                    // 尝试下一个候选命令
                }
            }
            if (!opened) {
                await tryRun('xdg-open', [extensionUrl]);
            }
        }
        logInfo('已尝试打开浏览器插件管理页面，如未自动弹出请手动前往。');
    } catch (error) {
        logWarning(`自动打开插件管理页面失败: ${error.message}`);
    }
}

async function installNikouPlugin(pluginDir, repoUrl) {
    const resolvedRepoUrl = repoUrl || 'https://gitee.com/vangelisx/chrome-nicole.git';
    if (!pluginDir) {
        throw new Error('未配置 nikou 插件目录，无法自动安装。');
    }
    const targetDir = path.resolve(pluginDir);
    const parentDir = path.dirname(targetDir);
    const repoName = path.basename(targetDir);
    const repoLabel = resolvedRepoUrl.split('/').pop().replace(/\.git$/, '');
    if (directoryHasFiles(targetDir)) {
        logInfo(`检测到已存在 nikou 插件目录: ${targetDir}`);
        return targetDir;
    }
    if (fs.existsSync(targetDir)) {
        logWarning(`检测到 nikou 插件目录 ${targetDir} 为空，将重新拉取仓库。`);
        fs.rmSync(targetDir, {recursive: true, force: true});
    }
    if (!fs.existsSync(parentDir)) {
        fs.mkdirSync(parentDir, {recursive: true});
        logSuccess(`已创建 nikou 插件父目录: ${parentDir}`);
    }
    logInfo(`开始下载 nikou 插件仓库 (${repoLabel})...`);
    const result = spawnSync('git', ['clone', resolvedRepoUrl, repoName], {
        cwd: parentDir,
        stdio: 'inherit'
    });
    if (result.status !== 0) {
        throw new Error('git clone nikou 插件仓库失败，请确认已安装 git 并有访问权限。请联系管理员');
    }
    logSuccess('nikou 插件仓库下载完成。');
    logSuccess(`插件目录: ${targetDir}`);
    return targetDir;
}

function setupGlobalGitHook() {
    const homeDir = os.homedir();
    const hooksDir = path.join(homeDir, '.githooks');
    const prePushPath = path.join(hooksDir, 'pre-push');
    const scriptContent = [
        '#!/bin/bash',
        '# 全局 Git pre-push 钩子',
        '',
        '# 只在普通仓库触发',
        'if [ ! -d ".git" ]; then',
        '    exit 0',
        'fi',
        '',
        '# 调用 AutoMerge 脚本',
        'echo "🚀 全局 pre-push: 执行 am"',
        'am "$@"',
        '',
        '# 返回 0 继续 push',
        'exit 0',
        ''
    ].join('\n');
    try {
        if (!fs.existsSync(hooksDir)) {
            fs.mkdirSync(hooksDir, {recursive: true});
            logSuccess(`创建全局 Git hooks 目录: ${hooksDir}`);
        } else {
            logInfo(`全局 Git hooks 目录已存在: ${hooksDir}`);
        }
        fs.writeFileSync(prePushPath, scriptContent, 'utf8');
        fs.chmodSync(prePushPath, 0o755);
        logSuccess(`全局 pre-push 钩子已写入: ${prePushPath}`);
        const result = spawnSync('git', ['config', '--global', 'core.hooksPath', hooksDir], {
            encoding: 'utf8',
            stdio: 'pipe'
        });
        if (result.status === 0) {
            logSuccess('已设置 git 全局 hooksPath 为 ~/.githooks');
        } else {
            const errMsg = result.stderr ? String(result.stderr).trim() : '未知错误';
            logWarning(`设置 git hooksPath 失败: ${errMsg}`);
        }
    } catch (error) {
        logError(`初始化全局 Git pre-push 钩子失败: ${error.message}`);
    }
}

async function pollOpsToken(opsUser) {
    while (true) {
        try {
            await fetchUserOpsToken(opsUser);
            logSuccess('检测到 nikou 插件已加载。');
            return;
        } catch (error) {
            logWarning(`仍未检测到 nikou 插件: ${error.message}，3 秒后重试...`);
            await delay(3000);
        }
    }
}

async function ensureNikouPluginAvailable(opsUser, pluginDir, rl, options = {}) {
    const {
        autoInstall = true,
        userLabel = '当前用户',
        onFailMessage,
        browserSelection = null,
        useDacs = false
    } = options;
    const resolvedPluginDir = pluginDir ? path.resolve(pluginDir) : '';
    if (!opsUser) {
        return resolvedPluginDir || null;
    }
    let repoSelectionCache = browserSelection || null;
    const ensureRepoSelection = async () => {
        if (!repoSelectionCache) {
            repoSelectionCache = await selectBrowser(rl, {useDacs});
            logInfo(`已选择 ${repoSelectionCache.browserLabel} 插件版本。`);
        }
        return repoSelectionCache;
    };

    const ensurePluginDirectoryReady = async () => {
        if (!autoInstall) {
            return resolvedPluginDir || null;
        }
        if (!resolvedPluginDir) {
            logError('未配置 nikou 插件目录，无法执行自动安装。请在配置文件中设置 nikou_plugin_path。');
            return null;
        }
        if (directoryHasFiles(resolvedPluginDir)) {
            return resolvedPluginDir;
        }
        const {repoUrl} = await ensureRepoSelection();
        try {
            await installNikouPlugin(resolvedPluginDir, repoUrl);
        } catch (error) {
            logError(`插件仓库拉取失败: ${error.message}`);
        }
        return resolvedPluginDir;
    };

    if (autoInstall) {
        await ensurePluginDirectoryReady();
    }

    try {
        await fetchUserOpsToken(opsUser);
        logSuccess(`检测到 ${userLabel} nikou 插件已加载。`);
        return resolvedPluginDir || null;
    } catch (error) {
        logWarning(`${userLabel} 获取用户 Token 失败: ${error.message}`);
        if (!autoInstall) {
            const message = onFailMessage || `请联系${userLabel}安装 nikou 浏览器插件后再试，可选择 Edge 或 Chrome 浏览器版本。`;
            logWarning(message);
            return resolvedPluginDir || null;
        }
    }

    logWarning('系统检测到 nikou 浏览器插件未就绪。');
    logInfo('如尚未安装，可访问 http://gitlab.inzwc.com/-/profile/personal_access_tokens 生成 Token 后继续。');
    const repoSelection = await ensureRepoSelection();
    await openGitLabTokenPage(repoSelection);

    await ensurePluginDirectoryReady();

    if (!resolvedPluginDir) {
        return null;
    }

    const {useChrome, browserLabel} = repoSelection;

    logInfo('============================================================');
    logInfo('【浏览器插件手动加载提示】');
    logInfo(`1. 请在 ${browserLabel} 浏览器的扩展管理页中点击“加载已解压的扩展程序”，选择目录: ${resolvedPluginDir}`);
    logInfo('2. 访问一次 https://vops.hszq8.com/，保持本终端窗口开启以便持续检测。');
    logInfo('※ nb-init 会持续检测插件是否生效，完成后返回终端继续。');
    logInfo('============================================================');
    await openBrowserExtensionsPage(useChrome ? 'chrome' : 'edge');

    await pollOpsToken(opsUser);
    return resolvedPluginDir;
}

// 检查目录并创建
function ensureDirectoryExists(dirPath) {
    if (!fs.existsSync(dirPath)) {
        fs.mkdirSync(dirPath, { recursive: true });
        logSuccess(`目录创建成功: ${dirPath}`);
        return true;
    } else {
        logInfo(`目录已存在: ${dirPath}`);
        return false;
    }
}

// 确保文件存在
function ensureFileExists(filePath) {
    const dir = path.dirname(filePath);
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
        logSuccess(`目录创建成功: ${dir}`);
    }

    if (!fs.existsSync(filePath)) {
        fs.writeFileSync(filePath, '', 'utf8');
        logSuccess(`文件创建成功: ${filePath}`);
    } else {
        logInfo(`文件已存在: ${filePath}`);
    }
}

function directoryHasFiles(dirPath) {
    try {
        if (!dirPath || !fs.existsSync(dirPath)) {
            return false;
        }
        const entries = fs.readdirSync(dirPath);
        return entries.length > 0;
    } catch (error) {
        logWarning(`检查目录内容失败 (${dirPath}): ${error.message}`);
        return false;
    }
}

// 解析properties文件
function parseProperties(content) {
    const properties = {};
    const lines = content.split('\n');

    for (const line of lines) {
        const trimmedLine = line.trim();
        if (trimmedLine && !trimmedLine.startsWith('#') && !trimmedLine.startsWith('!')) {
            const equalIndex = trimmedLine.indexOf('=');
            if (equalIndex > 0) {
                const key = trimmedLine.substring(0, equalIndex).trim();
                const value = trimmedLine.substring(equalIndex + 1).trim();
                properties[key] = value;
            }
        }
    }

    return properties;
}

// 将properties对象转换为文件内容
function propertiesToString(properties) {
    let content = '# OPS全局配置文件\n';
    content += `# 生成时间: ${new Date().toISOString()}\n\n`;

    for (const [key, value] of Object.entries(properties)) {
        content += `${key}=${value}\n`;
    }

    return content;
}

// 读取或创建properties文件
function readOrCreateProperties(filePath) {
    if (fs.existsSync(filePath)) {
        logInfo(`配置文件已存在，读取中: ${filePath}`);
        const content = fs.readFileSync(filePath, 'utf8');
        return parseProperties(content);
    } else {
        logWarning(`配置文件不存在，将创建新文件: ${filePath}`);
        return {};
    }
}

// 保存properties文件
function saveProperties(filePath, properties) {
    const content = propertiesToString(properties);
    fs.writeFileSync(filePath, content, 'utf8');
    logSuccess(`配置文件保存成功: ${filePath}`);
}

async function ensureOpsUserInFeishuGroup(opsUser) {
    const chatId = OPSConstant.OPS_CHAT_ID;
    if (!chatId) {
        logWarning('未配置默认飞书群聊，跳过自动拉群。');
        return;
    }
    const account = (opsUser || '').trim();
    if (!account) {
        logWarning('ops_user 未配置，无法自动加入飞书群。');
        return;
    }
    const email = account.includes('@') ? account : `${account}@hstong.com`;
    try {
        const bot = new FeishuBot(chatId);
        const userIds = await bot.fetchUserIdsByEmails([email]);
        if (!Array.isArray(userIds) || userIds.length === 0) {
            logWarning(`未找到 ${email} 对应的飞书账号，无法自动拉群。`);
            return;
        }
        const existingMemberIds = await bot.fetchChatMemberIds(chatId);
        const pendingUserIds = userIds.filter(userId => !existingMemberIds.has(userId));
        if (pendingUserIds.length === 0) {
            logInfo(`检测到 ${email} 已在默认飞书群中，忽略拉群操作。`);
            return;
        }
        const success = await bot.addMembersToChat(pendingUserIds, chatId);
        if (success) {
            logSuccess(`已将 ${email} 加入飞书群聊，请关注飞书入群通知。`);
        } else {
            logWarning(`飞书拉群操作未返回成功，user_id 列表: ${pendingUserIds.join(', ')}`);
        }
    } catch (error) {
        logWarning(`自动拉群失败: ${error.message}`);
    }
}

/**
 * nb-init 主执行函数
 * @param {string[]} args - 命令行参数
 */
async function executeInit(args) {
    let rl = null;

    try {
        logInfo('开始初始化 nb-init 配置...');

        // 创建readline接口
        rl = createReadlineInterface();

        const currentDir = process.cwd();
        logInfo('正在检测环境...');
        logInfo(`当前目录 (pwd): ${currentDir}`);

        const detectedDacsContext = extractDacsContext(currentDir);
        const useDacs = await askDacsUsagePreference(rl, Boolean(detectedDacsContext));
        const dacsContext = detectedDacsContext;

        if (useDacs && !dacsContext) {
            throw new Error('未检测到 /meili/.../103 路径或 Windows O:/P: 域内盘符，请在域内执行此指令。');
        }
        if (!useDacs && dacsContext) {
            throw new Error('当前为 DACS 域内环境，请检查。');
        }

        const homeDir = os.homedir();
        logInfo(`检测到用户目录: ${homeDir}`);

        const systemUserName = useDacs && dacsContext ? dacsContext.dacsUser : os.userInfo().username;
        const opsRootDir = useDacs && dacsContext ? dacsContext.opsRootDir : path.join(homeDir, 'ops');

        if (useDacs) {
            logInfo(`已识别 DACS 域内环境，账号: ${systemUserName}，基础目录: ${opsRootDir}`);
        } else {
            logInfo('检测到域外环境，沿用默认基础目录。');
        }

        // 步骤1: 检查和创建目录结构
        logInfo('步骤1: 初始化基础目录...');

        ensureDirectoryExists(opsRootDir);

        const projectGlobalPath = path.join(opsRootDir, 'project_global.conf');
        ensureFileExists(projectGlobalPath);

        logInfo(`项目缓存文件位置: ${projectGlobalPath}`);

        // 步骤2: 创建或读取配置文件
        logInfo('步骤2: 处理配置文件...');

        const configFile = path.join(opsRootDir, 'ops_global.properties');
        let properties = readOrCreateProperties(configFile);

        // 步骤3: 检查和配置各项属性
        logInfo('步骤3: 配置参数检查...');

        const defaultOpsUser = properties.ops_user || systemUserName;
        if (!properties.ops_user) {
            logWarning('未找到 ops_user 配置');
        } else {
            logInfo(`已有 ops_user 配置: ${properties.ops_user}`);
        }
        const opsUserInput = await askQuestion(rl, `请输入用户工号 (默认: ${defaultOpsUser})，输入完成后按回车确认`);
        properties.ops_user = opsUserInput.trim() || defaultOpsUser;
        logSuccess(`ops_user 设置为: ${properties.ops_user}`);

        const browserSelection = await selectBrowser(rl, {useDacs});
        logInfo(`已选择 ${browserSelection.browserLabel} 插件版本，将使用该浏览器进行后续操作。`);

        // 检查 git_private_token
        if (!properties.git_private_token) {
            logWarning('未找到 git_private_token 配置');
            logInfo('请访问 GitLab 个人 Access Token 页面生成或复制 Token: http://gitlab.inzwc.com/-/profile/personal_access_tokens');
            await openGitLabTokenPage(browserSelection);
            let tokenValue = '';
            while (!tokenValue.trim()) {
                const tokenInput = await askQuestion(rl, '请输入 git_private_token (必填，直接粘贴后回车): ');
                tokenValue = tokenInput.trim();
                if (!tokenValue) {
                    logWarning('git_private_token 不能为空，如需退出可按 Ctrl+C。');
                }
            }
            properties.git_private_token = tokenValue;
            logSuccess('git_private_token 设置完成');
        } else {
            logInfo('检测到已有 git_private_token 配置。');
            logInfo('如需更新，可在 GitLab 页面生成新的 Token: http://gitlab.inzwc.com/-/profile/personal_access_tokens');
            const tokenInput = await askQuestion(rl, '输入新的 git_private_token 更新配置，直接回车保留现有值: ');
            if (tokenInput.trim()) {
                properties.git_private_token = tokenInput.trim();
                logSuccess('git_private_token 已更新');
            }
        }

        // 检查 ops_password
        if (!properties.ops_password) {
            logWarning('未找到 ops_password 配置');
            const userInput = await askQuestion(rl, `请输入用户[${properties.ops_user}]对应 Ops 密码（输入后按回车确认）: `);
            properties.ops_password = userInput.trim();
        } else {
            logInfo(`已有 ops_password 配置: ${properties.ops_password}`);
            const userInput = await askQuestion(rl, `可输入其他值或直接回车使用当前值 (${properties.ops_password}): `);
            if (userInput.trim()) {
                properties.ops_password = userInput.trim();
            }
        }
        logSuccess(`ops_password 设置为: ${properties.ops_password}`);

        // 检查 ops_path
        const defaultOpsPath = properties.ops_path || opsRootDir;
        if (!properties.ops_path) {
            logWarning('未找到 ops_path 配置');
        } else {
            logInfo(`已有 ops_path 配置: ${properties.ops_path}`);
        }
        const pathInput = await askQuestion(rl, `请输入 ops 工作目录 (默认: ${defaultOpsPath})，输入完成后按回车确认: `);
        properties.ops_path = pathInput.trim() || defaultOpsPath;
        logSuccess(`ops_path 设置为: ${properties.ops_path}`);
        ensureDirectoryExists(properties.ops_path);

        // 检查 code_path
        const defaultCodePath = properties.code_path || properties.ops_path;
        if (!properties.code_path) {
            logWarning('未找到 code_path 配置');
            const codePathInput = await askQuestion(rl, `请输入代码路径 (默认: ${defaultCodePath}，直接回车使用默认值): `);
            properties.code_path = codePathInput.trim() || defaultCodePath;
        } else {
            logInfo(`已有 code_path 配置: ${properties.code_path}`);
            const codePathInput = await askQuestion(rl, `请输入代码路径 (直接回车使用当前值 ${properties.code_path}): `);
            properties.code_path = codePathInput.trim() || properties.code_path;
        }
        logSuccess(`code_path 设置为: ${properties.code_path}`);

        // 确保code目录存在
        ensureDirectoryExists(properties.code_path);

        // 配置 nikou 插件目录（默认放在 code_path 下）
        const resolvedNikouPath = properties.nikou_plugin_path
            ? path.resolve(properties.nikou_plugin_path)
            : path.resolve(path.join(properties.code_path, 'chrome-nicole'));
        if (!properties.nikou_plugin_path) {
            logWarning('未找到 nikou 插件目录配置，将自动使用默认路径。');
        } else {
            logInfo(`沿用已有 nikou_plugin_path 配置: ${properties.nikou_plugin_path}`);
        }
        properties.nikou_plugin_path = resolvedNikouPath;
        logSuccess(`nikou_plugin_path 设置为: ${properties.nikou_plugin_path}`);

        // 检查 easysearch_default_index，默认填充 buzz-service
        if (!properties.easysearch_default_index) {
            properties.easysearch_default_index = 'buzz-service';
            logWarning('未找到 easysearch_default_index 配置，已自动设置为 buzz-service。');
        } else {
            logInfo(`沿用已有 easysearch_default_index 配置: ${properties.easysearch_default_index}`);
        }
        logSuccess(`easysearch_default_index 设置为: ${properties.easysearch_default_index}`);

        // 初始化全局 Git pre-push 钩子
        setupGlobalGitHook();

        // 校验 nikou 插件及用户 token
        const ensuredPluginPath = await ensureNikouPluginAvailable(properties.ops_user, properties.nikou_plugin_path, rl, {
            browserSelection,
            useDacs
        });
        if (ensuredPluginPath) {
            properties.nikou_plugin_path = ensuredPluginPath;
        }

        const normalizedOpsUser = (properties.ops_user || '').trim().toLowerCase();
        const needLeaderConfig = normalizedOpsUser && !SKIP_LEADER_USERS.has(normalizedOpsUser);

        let opsUserToken = null;
        if (needLeaderConfig) {
            try {
                opsUserToken = await fetchUserOpsToken(properties.ops_user);
            } catch (error) {
                logWarning(`获取组长账号前尝试登录失败: ${error.message}`);
            }
        }

        if (needLeaderConfig) {
            let leaderAccount = null;
            if (opsUserToken) {
                try {
                    const client = opsClient(opsUserToken, false);
                    leaderAccount = await client.fetchInformMemberAccount();
                    if (leaderAccount) {
                        logSuccess(`已自动获取组长账号: ${leaderAccount}`);
                    }
                } catch (error) {
                    logWarning(`自动获取组长账号失败: ${error.message}`);
                }
            }

            if (leaderAccount) {
                properties.zz_ops_user = leaderAccount;
            } else if (properties.zz_ops_user) {
                logInfo(`保留已有 zz_ops_user 配置: ${properties.zz_ops_user}`);
            } else {
                logWarning('未能自动获取组长账号，请稍后手动补充 zz_ops_user 配置。');
            }
        } else {
            logInfo('检测到当前用户无需维护组长信息，跳过 zz_ops_user 配置。');
            if (properties.zz_ops_user) {
                logInfo('将清理历史 zz_ops_user 配置，避免误用。');
                delete properties.zz_ops_user;
            }
        }

        if (needLeaderConfig && properties.zz_ops_user) {
            await ensureNikouPluginAvailable(properties.zz_ops_user, properties.nikou_plugin_path, rl, {
                autoInstall: false,
                userLabel: '组长',
                onFailMessage: '系统检测到组长尚未安装 nikou 浏览器插件，请联系组长完成安装后继续，可选择 Edge 或 Chrome 浏览器版本。',
                useDacs
            });
        }

        // 保存配置文件
        saveProperties(configFile, properties);

        await ensureOpsUserInFeishuGroup(properties.ops_user);

        // 步骤4: 完成提示
        console.log(chalk.green('='.repeat(50)));
        logSuccess('初始化完成！');
        logSuccess(`配置文件位置: ${configFile}`);
        console.log(chalk.green('='.repeat(50)));

        console.log('\n当前配置内容:');
        console.log(chalk.gray('-'.repeat(30)));
        for (const [key, value] of Object.entries(properties)) {
            console.log(`${chalk.cyan(key)} = ${chalk.white(value)}`);
        }
        console.log(chalk.gray('-'.repeat(30)));

    } catch (error) {
        logError(`初始化过程中发生错误: ${error.message}`);
        throw error;
    } finally {
        if (rl) {
            rl.close();
        }
    }
}

/**
 * 命令处理器导出函数
 * @param {string[]} args - 命令行参数
 */
export async function execute(args) {
    // 处理Ctrl+C退出
    const handleExit = () => {
        console.log(chalk.yellow('\n\n用户取消操作'));
        process.exit(0);
    };

    process.on('SIGINT', handleExit);

    try {
        await executeInit(args);
    } catch (error) {
        logError(`nb-init 执行失败: ${error.message}`);
        process.exit(1);
    } finally {
        process.removeListener('SIGINT', handleExit);
    }
}
